package com.daoliuhe.scaffold.realms;

import com.daoliuhe.scaffold.model.Role;
import com.daoliuhe.scaffold.model.User;
import com.daoliuhe.scaffold.service.UserService;
import com.daoliuhe.scaffold.tools.Constants;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.Set;

@Component
public class SimpleLDAPRealm extends AuthorizingRealm {

    private static final Logger logger = LoggerFactory.getLogger(SimpleLDAPRealm.class);

    @Autowired
    UserService userService;

    /*
     * (non-Javadoc)
     *
     * @see
     * org.apache.shiro.realm.AuthenticatingRealm#doGetAuthenticationInfo(org.
     * apache.shiro.authc.AuthenticationToken) 身份验证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
            throws AuthenticationException {
        logger.debug("doGetAuthenticationInfo");
        // 获取登录信息
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String userName = token.getUsername();
        String password = String.valueOf(token.getPassword());
        //查询用户是否禁用
        User user = userService.getUserByLoginId(userName);
        if (user != null) {
            if (Constants.DISABLE.equals(user.getEnabled())) {
                // 用户被禁用
                throw new LockedAccountException();
            }
            // 参数是需要验证的对象, 证明身份的证书, 验证Realm名称
            return new SimpleAuthenticationInfo(userName, password, getName());
        }
        // A null return value means that no account could be associated with
        // the specified token.
        // 返回null表示不存在当前用户
        return null;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String loginId = (String) principalCollection.getPrimaryPrincipal();
        logger.debug("doGetAuthorizationInfo, loginId:{}", loginId);
        //角色集合
        Set<String> roles = new HashSet<String>();
        //权限集合
        Set<String> permissions = new HashSet<String>();
        //授权
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //角色集合
        Set<Role> userRoles = userService.getRolesByLoginId(loginId);
        for (Role role : userRoles) {
            roles.add(role.getName());
        }
        //roles.addAll(userService.getRolesByUserLoginId(loginId));
        logger.debug("doGetAuthorizationInfo, roles:{}", roles.toString());
        //权限集合
        permissions.addAll(userService.getPermissionsByRoles(userRoles));
        logger.debug("doGetAuthorizationInfo, permissions:{}", permissions.toString());

        info.setStringPermissions(permissions);
        info.setRoles(roles);
        return info;
    }

    @Override
    public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
        super.clearCachedAuthorizationInfo(principals);
    }

    @Override
    public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
        super.clearCachedAuthenticationInfo(principals);
    }

    @Override
    public void clearCache(PrincipalCollection principals) {
        super.clearCache(principals);
    }

    public void clearAllCachedAuthorizationInfo() {
        getAuthorizationCache().clear();
    }

    public void clearAllCachedAuthenticationInfo() {
        getAuthenticationCache().clear();
    }

    public void clearAllCache() {
        clearAllCachedAuthenticationInfo();
        clearAllCachedAuthorizationInfo();
    }
}
